package com.bishe.app.modules.userSaleIncome.controller;

import cn.hutool.core.lang.Pair;
import cn.hutool.core.util.ReflectUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bishe.app.core.api.CommonPage;
import com.bishe.app.core.api.CommonResult;
import com.bishe.app.core.common.BizException;
import com.bishe.app.core.enums.IsDel;
import com.bishe.app.core.utils.ImgUtils;
import com.bishe.app.core.utils.Lock;
import com.bishe.app.modules.group.entity.Group;
import com.bishe.app.modules.group.service.GroupService;
import com.bishe.app.modules.user.service.UserService;
import com.bishe.app.modules.userSaleIncome.entity.UserSaleIncome;
import com.bishe.app.modules.userSaleIncome.model.*;
import com.bishe.app.modules.userSaleIncome.service.UserSaleIncomeService;
import com.bishe.app.modules.usersaledetail.model.MonthSaleDetailReq;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;


/**
 * <p>
 * 用户当月提成信息 前端控制器
 * </p>
 *
 * @author
 * @since 2024-03-31
 */
@RestController
@RequestMapping("/userSaleIncome")
public class UserSaleIncomeController {

    @Autowired
    public UserSaleIncomeService userSaleIncomeService;

    @Resource
    private GroupService groupService;

    @Resource
    private UserService userService;

    @RequestMapping(value = "/create", method = RequestMethod.POST)
    @ResponseBody
    @Lock(lockPrefix = "/userSaleIncome",key = "#userSaleIncome.userId", lockSecond = 60)
    public CommonResult create(@RequestBody UserSaleIncome userSaleIncome) {
        boolean success = userSaleIncomeService.save(userSaleIncome);
        if (success) {
            return CommonResult.success(null);
        }
        return CommonResult.failed();
    }

    @RequestMapping(value = "/getSalary", method = RequestMethod.POST)
    @ResponseBody
    public void getUserSalary(@RequestBody UserSalaryReq req, HttpServletRequest request, HttpServletResponse response) throws Exception {
        UserSaleIncome income = userSaleIncomeService.getUserIncome(req.getGroupId(), req.getUserId(), req.getYear(), req.getMon());
        UserSaleIncomeDetailModel userSaleIncomeDetailModel = null;
        if (income == null) {
            userSaleIncomeDetailModel = UserSaleIncomeDetailModel.init();
        } else {
            userSaleIncomeDetailModel = JSON.parseObject(income.getSaleItem(), UserSaleIncomeDetailModel.class);
        }


        UserSalaryModel userSalaryModel = new UserSalaryModel(req.getUserId(), req.getGroupId(), Optional.ofNullable(userSaleIncomeDetailModel).orElse(UserSaleIncomeDetailModel.init()));

        BufferedImage img = ImgUtils.img(userSalaryModel.genImgData());
        // 设置响应头信息
        String filename = userSalaryModel.getName() + LocalDate.of(req.getYear(),req.getMon(),1).format(DateTimeFormatter.ofPattern("yyyyMM")) + "工资条.jpeg";
        response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(filename,"UTF-8"));
        response.setContentType("application/octet-stream");
        // 将BufferedImage写入response输出流
        try {
            OutputStream os = response.getOutputStream();
            ImageIO.write(img, "jpeg", os);
            os.flush();
            os.close();
        } catch (Exception e) {
            throw new BizException("下载失败，请联系管理员");
        }
    }

    @RequestMapping(value = "/createOrUpdate", method = RequestMethod.POST)
    @ResponseBody
    @Lock(lockPrefix = "/userSaleIncome",key = "#userSaleIncome.userId", lockSecond = 60)
    @Transactional(rollbackFor = Throwable.class)
    public CommonResult createOrUpdate(@RequestBody UserIncomeCreateOrUpdate userSaleIncome) {
        UserSaleIncome userIncome = userSaleIncomeService.getUserIncome(userSaleIncome.getGroupId(),
                userSaleIncome.getUserId(), userSaleIncome.getYear(), userSaleIncome.getMon());

        if (userIncome == null) {
            userIncome = new UserSaleIncome();
            userIncome.setUserId(userSaleIncome.getUserId());
            userIncome.setGroupId(userSaleIncome.getGroupId());
            userIncome.setSaleItem("{}");
            userIncome.setYear(userSaleIncome.getYear());
            userIncome.setMon(userSaleIncome.getMon());
        }

        // 更新detail
        String saleItem = userIncome.getSaleItem();
        UserSaleIncomeDetailModel userSaleIncomeDetailModel = JSON.parseObject(saleItem,
                UserSaleIncomeDetailModel.class);

        ReflectUtil.setFieldValue(userSaleIncomeDetailModel, userSaleIncome.getField(),
                userSaleIncome.getVal());

        userIncome.setSaleItem(JSON.toJSONString(userSaleIncomeDetailModel));
        userSaleIncomeService.saveOrUpdate(userIncome);

        // 计算实际发放工资
        userSaleIncomeService.reCalcShifagongzi(userSaleIncome.getGroupId(), userSaleIncome.getUserId(), userSaleIncome.getYear(), userSaleIncome.getMon());

        return CommonResult.success(null);
    }


    @RequestMapping(value = "/getUserSaleIncome", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult create(@RequestBody MonthSaleDetailReq req) {
        List<UserSaleIncome> list = userSaleIncomeService.lambdaQuery()
                .eq(UserSaleIncome::getGroupId, req.getGroupId())
                .eq(UserSaleIncome::getYear, req.getYear())
                .eq(UserSaleIncome::getMon, req.getMon())
                .eq(UserSaleIncome::getIsDel, IsDel.N.getCode())
                .list();

        Group group = groupService.getById(req.getGroupId());

        List<Map<String, String>> saleDTO = new ArrayList<>();

        List<Pair<String, String>> kvs = UserIncomeKV.getGroupKvs(group.getType());
        for (Pair<String, String> kv : kvs) {
            Map<String, String> maps = new HashMap<>();
            maps.put("key", kv.getKey());
            maps.put("value", kv.getValue());
            for (UserSaleIncome userSaleIncome : list) {
                String saleItem = userSaleIncome.getSaleItem();
                UserSaleIncomeDetailModel userSaleIncomeDetailModel = JSON.parseObject(saleItem, UserSaleIncomeDetailModel.class);
                String val = Optional.ofNullable(ReflectUtil.getFieldValue(userSaleIncomeDetailModel, (String) kv.getValue())).map(Object::toString).orElse("0");
                maps.put("user" + userSaleIncome.getUserId(), val);
            }

            saleDTO.add(maps);
        }

        return CommonResult.success(saleDTO);
    }

    @RequestMapping(value = "/update/{id}", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult update(@PathVariable Long id, @RequestBody UserSaleIncome userSaleIncome) {
        userSaleIncome.setId(id);
        boolean success = userSaleIncomeService.updateById(userSaleIncome);
        if (success) {
            return CommonResult.success(null);
        }
        return CommonResult.failed();
    }

    @RequestMapping(value = "/delete/{id}", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult delete(@PathVariable Long id) {
        boolean success = userSaleIncomeService.removeById(id);
        if (success) {
            return CommonResult.success(null);
        }
        return CommonResult.failed();
    }

    @RequestMapping(value = "/delete", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult deleteBatch(@RequestParam("ids") List<Long> ids) {
        boolean success = userSaleIncomeService.removeByIds(ids);
        if (success) {
            return CommonResult.success(null);
        }
        return CommonResult.failed();
    }


    @RequestMapping(value = "/listAll", method = RequestMethod.GET)
    @ResponseBody
    public CommonResult<List<UserSaleIncome>> listAll() {
        List<UserSaleIncome> userSaleIncomeList = userSaleIncomeService.list();
        return CommonResult.success(userSaleIncomeList);
    }

    @RequestMapping(value = "/pageList", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult<CommonPage<UserSaleIncome>> page(@RequestBody CommonPage commonPage) {
        Page<UserSaleIncome> page = new Page(commonPage.getPageNum(), commonPage.getPageSize());
        return CommonResult.success(CommonPage.restPage(userSaleIncomeService.page(page)));
    }
}



